package com.houger.ddd.redpacket.infra.redis;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.houger.ddd.redpacket.application.GrabRedPacketAdaptor;
import com.houger.ddd.redpacket.application.RedPacketAdaptor;
import com.houger.ddd.redpacket.facade.dto.RedPacketDto;
import com.houger.ddd.redpacket.domain.GrabRedPacketDomain;
import com.houger.ddd.redpacket.domain.RedPacketDomain;
import com.houger.ddd.redpacket.infra.entity.GrabRedPacket;
import com.houger.ddd.redpacket.infra.entity.RedPacket;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Repository;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author Houger.
 * @date 2024年04月18日 18:15.
 */
@Slf4j
@Repository
public class RedisRepository {
    private final static String rp_send_key="rp:send:hash:{%s}";
    private final static String rp_grab_key="rp:grab:hash:{%s}";
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource(name = "sendRedPacketLuaScript")
    RedisScript<String> sendRedPacketLuaScript;

    @Resource(name = "grabRedPacketLuaScript")
    RedisScript<String> grabRedPacketLuaScript;

    public String initRedPacket(RedPacketDomain domain) {
        final RedPacket entity = RedPacketAdaptor.toEntity(domain);
        List<String> keys = List.of(rp_send_key.formatted(entity.getRedPacketId()));
        return stringRedisTemplate.execute(sendRedPacketLuaScript, keys, entity.getResidualAmount(),
            entity.getResidualCount(), entity.getSendTime(),entity.getIsOnlyMinAmount().toString());
    }

    public Integer grab(final GrabRedPacketDomain domain) {
        final String money = grabRedPacket(GrabRedPacketAdaptor.toEntity(domain));
        log.info(money);
        if ("1".equals(money)) return 1;
        if ("-1".equals(money)) return -1;
        domain.setMoney(money);
        return 200;
    }

    public String grabRedPacket(final GrabRedPacket entity) {
        List<String> keys = Arrays.asList(rp_send_key.formatted(entity.getRedPacketId()),
            rp_grab_key.formatted(entity.getRedPacketId()));
        return stringRedisTemplate.execute(grabRedPacketLuaScript, keys, entity.getUserId(),entity.getGrabTime());
    }

    public void saveByDb(RedPacket entity){
        final RedPacketDto redPacketDto = RedPacketAdaptor.entityToDto(entity);
//        对象转map
        ObjectMapper objectMapper = new ObjectMapper();
        final Map map = objectMapper.convertValue(redPacketDto, Map.class);
        stringRedisTemplate.opsForHash().putAll(rp_send_key.formatted(entity.getRedPacketId()),map);
    }

    public Map<Object, Object> getGrabRedPacketInfoList(final String redPacketId) {

        return stringRedisTemplate.opsForHash().entries(rp_grab_key.formatted(redPacketId));

    }

    public Map<Object, Object> getRedPacketByCache(final String redPacketId) {
        return stringRedisTemplate.opsForHash().entries(rp_send_key.formatted(redPacketId));
    }

    public String getBurnoutTime(final String redPacketId) {
        return (String) stringRedisTemplate.opsForHash().get(rp_send_key.formatted(redPacketId),"burnoutTime");
    }

}
